<template>
  <div class="app-container" :class="{ 'dark': darkMode }">
    <!-- 顶部导航栏 -->
    <el-header class="app-header" height="60px">
      <div class="header-content">
        <el-text class="app-title" type="primary" size="large" tag="b">
          绿色方舟智能顾问
        </el-text>
        <div class="header-actions">
          <el-button type="success" :icon="Plus" circle @click="startNewConversation" />
        </div>
      </div>
    </el-header>

    <!-- 聊天内容区域 -->
    <main class="chat-container">
      <div v-for="(message, index) in messages" :key="index" class="message-wrapper">
        <div class="message-item" :class="message.role">
          <div class="avatar" :class="message.role">
            <el-icon v-if="message.role === 'user'">
              <User />
            </el-icon>
            <el-icon v-else>
              <Promotion />
            </el-icon>
          </div>
          <div class="message-content" :class="message.role">
            <template v-if="message.isLoading">
              <div class="loading-dots">
                <span v-for="i in 3" :key="i" class="dot" :class="`delay-${i}00`" />
              </div>
            </template>
            <template v-else>
              <div class="message-text" v-html="renderMarkdown(message.content)" 
                   :class="{ 'markdown-body': message.role === 'assistant' }">
              </div>
              <span v-if="message.isStreaming" class="typing-cursor"></span>
            </template>
          </div>
        </div>
      </div>
    </main>

    <!-- 输入框区域 -->
    <footer class="input-area">
      <div class="input-group" style="display: flex; gap: 8px;">
        <el-input v-model="userInput" type="textarea" :rows="2" :autosize="{ minRows: 2, maxRows: 4 }"
          placeholder="输入您的问题..." @keydown.enter.exact.prevent="sendMessage" resize="none" style="flex: 1;" />
        <el-button :type="isLoading ? 'danger' : 'primary'" :disabled="!userInput.trim() && !isLoading"
          @click="isLoading ? stopResponse() : sendMessage()">
          {{ isLoading ? '停止' : '发送' }}
        </el-button>
      </div>
    </footer>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, watch } from 'vue'
import { ElHeader, ElText, ElButton, ElSwitch, ElInput, ElIcon } from 'element-plus'
import { User, Promotion, Plus, Moon, Sunny, Position, SwitchButton } from '@element-plus/icons-vue'
import { marked } from 'marked'

// 设置 marked 选项
marked.setOptions({
  breaks: true,
  gfm: true
})

// 状态管理
const messages = ref([])
const userInput = ref('')
const isLoading = ref(false)
const memoryId = ref(Date.now().toString())

// 控制器和定时器 
let controller = null
let typingInterval = null

// 工具函数
const scrollToBottom = () => {
  nextTick(() => {
    const container = document.querySelector('.chat-container')
    if (container) {
      container.scrollTop = container.scrollHeight
    }
  })
}

// 渲染 Markdown 内容
const renderMarkdown = (content) => {
  if (!content) return ''
  return marked.parse(content)
}

const startNewConversation = () => {
  messages.value = []
  memoryId.value = Date.now().toString()
  addAssistantMessage('你好！我是绿色方舟提供的AI助手，请问有什么能帮到您？')
}

const addAssistantMessage = (content) => {
  messages.value.push({
    role: 'assistant',
    content,
    isLoading: false,
    visibleChars: 0,
    isStreaming: false
  })
  // 直接显示完整消息
  messages.value[messages.value.length - 1].visibleChars = content.length
  scrollToBottom()
}

const startTypingEffect = (messageIndex) => {
  const message = messages.value[messageIndex]
  if (!message || message.visibleChars >= message.content.length) {
    clearInterval(typingInterval)
    typingInterval = null
    messages.value[messageIndex].isStreaming = false
    return
  }

  messages.value[messageIndex].visibleChars++
  scrollToBottom()
}

// 主要功能 
const sendMessage = async () => {
  if (!userInput.value.trim() || isLoading.value) return;

  if (controller) {
    controller.abort();
  }
  controller = new AbortController();

  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: userInput.value.trim(),
    visibleChars: userInput.value.trim().length,
    isStreaming: false,
    isLoading: false
  });

  // 添加助手占位消息
  messages.value.push({
    role: 'assistant',
    content: '',
    visibleChars: 0,
    isStreaming: true,
    isLoading: true
  });

  const userMessage = userInput.value.trim();
  userInput.value = '';
  scrollToBottom();
  isLoading.value = true;

  const messageIndex = messages.value.length - 1;

  try {
    const response = await fetch('/api/ai/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({
        memoryId: memoryId.value,
        message: userMessage
      }),
      signal: controller.signal
    });

    if (!response.ok) throw new Error('Network response was not ok');

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let result = '';

    while (true) {
      const { done, value } =  await reader.read();
      if (done) break;

      const chunk = decoder.decode(value, { stream: true });
      result += chunk;

      messages.value[messageIndex].content = result;
      messages.value[messageIndex].isLoading = false;

      if (!typingInterval) {
        typingInterval = setInterval(() => {
          startTypingEffect(messageIndex);
        }, 20);
      }

      scrollToBottom();
    }

    clearInterval(typingInterval);
    typingInterval = null;
    messages.value[messageIndex].isStreaming = false;
    messages.value[messageIndex].visibleChars = result.length;
    isLoading.value = false;

  } catch (error) {
    if (error.name === 'AbortError') {
      console.log(' 请求被用户中止');
    } else {
      console.error(' 请求出错:', error);
      const lastMessage = messages.value[messages.value.length - 1];
      lastMessage.content = '抱歉，请求过程中出现错误: ' + error.message;
      lastMessage.visibleChars = lastMessage.content.length;
      lastMessage.isLoading = false;
      lastMessage.isStreaming = false;
    }
  } finally {
    isLoading.value = false;
    controller = null;
  }
};

const stopResponse = () => {
  if (controller) {
    controller.abort()
    const lastMessage = messages.value[messages.value.length - 1]
    lastMessage.isLoading = false
    lastMessage.isStreaming = false
    lastMessage.visibleChars = lastMessage.content.length
    isLoading.value = false
    controller = null

    if (typingInterval) {
      clearInterval(typingInterval)
      typingInterval = null
    }
  }
}

// 初始化
onMounted(() => {
  addAssistantMessage('你好！我是绿色方舟提供的AI助手，请问有什么能帮到您？')
})

// 监听消息变化自动滚动 
watch(messages, scrollToBottom, { deep: true })
</script>

<style scoped>
.app-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f7fa;
  transition: background-color 0.3s;
}

.app-header {
  padding: 0 20px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  align-items: center;
  background-color: #ffffff;
}

.header-content {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.app-title {
  font-size: 18px;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.chat-container {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
  padding-bottom: 80px; /* 防止被输入框遮挡 */
}

.message-wrapper {
  margin-bottom: 16px;
}

.message-item {
  display: flex;
  max-width: 80%;
}

.message-item.user {
  margin-left: auto;
  justify-content: flex-end;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 4px;
}

.avatar.user {
  background-color: #d9ecff;
  color: #409eff;
  margin-left: 12px;
}

.avatar.assistant {
  background-color: #e1f3d8;
  color: #67c23a;
  margin-right: 12px;
}

.message-content {
  padding: 12px 16px;
  border-radius: 8px;
  word-break: break-word;
  line-height: 1.5;
}

.message-content.user {
  background-color: #409eff;
  color: white;
  border-top-right-radius: 0;
}

.message-content.assistant {
  background-color: #e9f1fa;
  color: #303133;
  border-top-left-radius: 0;
}

/* Markdown 样式 */
.markdown-body {
  overflow-wrap: break-word;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3 {
  margin-top: 16px;
  margin-bottom: 10px;
  font-weight: 600;
  line-height: 1.25;
}

.markdown-body h1 {
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.markdown-body h2 {
  font-size: 1.3em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.markdown-body h3 {
  font-size: 1.2em;
}

.markdown-body p {
  margin-top: 0;
  margin-bottom: 10px;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 20px;
  margin-top: 0;
  margin-bottom: 10px;
}

.markdown-body li {
  margin-bottom: 5px;
}

.markdown-body pre {
  background-color: #f6f8fa;
  border-radius: 6px;
  padding: 12px;
  overflow: auto;
  margin-top: 10px;
  margin-bottom: 10px;
}

.markdown-body code {
  background-color: #f6f8fa;
  border-radius: 6px;
  padding: 2px 4px;
  font-family: monospace;
}

.markdown-body pre code {
  background: none;
  padding: 0;
}

.markdown-body blockquote {
  margin: 0;
  padding: 0 1em;
  color: #6a737d;
  border-left: 0.25em solid #dfe2e5;
  margin-bottom: 10px;
}

.markdown-body table {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 10px;
}

.markdown-body th,
.markdown-body td {
  border: 1px solid #dfe2e5;
  padding: 6px 13px;
}

.markdown-body th {
  background-color: #f6f8fa;
  font-weight: 600;
}

.input-area {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 16px 20px;
  border-top: 1px solid #ebeef5;
  background-color: #ffffff;
  z-index: 999;
}

.input-container {
  max-width: 800px;
  margin: 0 auto;
}

.input-group {
  display: flex;
  gap: 8px;
  max-width: 600px;
  margin: 0 auto;
}

.loading-dots {
  display: flex;
  align-items: center;
  height: 24px;
  padding: 0 8px;
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #909399;
  margin-right: 4px;
  animation: pulse 1.4s infinite ease-in-out;
}

.dot.delay-100 {
  animation-delay: 0.2s;
}

.dot.delay-200 {
  animation-delay: 0.4s;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.3;
    transform: scale(0.8);
  }

  50% {
    opacity: 1;
    transform: scale(1);
  }
}

.message-text {
  position: relative;
}

.invisible {
  opacity: 0;
}

.fade-in {
  animation: fadeIn 0.1s forwards;
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}

.typing-cursor::after {
  content: "|";
  animation: blink 1s step-end infinite;
  color: inherit;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }
}
</style>